#ifndef BLOOM_H
#define BLOOM_H

#include "Shader.h"
#include "RenderTarget.h"

#include "Helper.h"

class Bloom
{
public:

	Bloom() {}
	~Bloom() {}

	enum ToneMapOperator {
		TONEMAP_LINEAR = 0,
		TONEMAP_EXPONENTIAL = 1,
		TONEMAP_EXPONENTIAL_HSV = 2,
		TONEMAP_REINHARD = 3,
		TONEMAP_FILMIC = 4
	};

	static void static_init()
	{
        //IOS_PATH("shader", "Quad", "vert"), IOS_PATH("shader", "Bloom_ToneMap", "frag")
		shader_glare_detection.init(IOS_PATH("shader", "Quad", "vert"), IOS_PATH("shader", "Bloom_GlareDetection", "frag"));
		shader_blur.init(IOS_PATH("shader", "Quad", "vert"), IOS_PATH("shader", "Bloom_Blur", "frag"));
		shader_combine.init(IOS_PATH("shader", "Quad", "vert"), IOS_PATH("shader", "Bloom_Combine", "frag"));
		//shader_tonemap.init(IOS_PATH("shader", "Quad", "vert"), IOS_PATH("shader", "Bloom_ToneMap", "frag"));
	}

	void init(ToneMapOperator toneMapOperator, float exposure,
		float bloomThreshold, float bloomWidth, float bloomIntensity,
		float defocus);

	void resize(int width, int height);

	ToneMapOperator getToneMapOperator() const { return toneMapOperator; }

	void setExposure(float exposure) { this->exposure = exposure; }
	float getExposure() const { return exposure; }

	void setBurnout(float burnout) { this->burnout = burnout; }
	float getBurnout() const { return burnout; }

	void setBloomThreshold(float bloomThreshold) { this->bloomThreshold = bloomThreshold; }
	float getBloomThreshold() const { return bloomThreshold; }

	void setBloomWidth(float bloomWidth) { this->bloomWidth = bloomWidth; }
	float getBloomWidth() const { return bloomWidth; }

	void setBlooomIntensity(float bloomIntensity) { this->bloomIntensity = bloomIntensity; }
	float getBloomIntensity() const { return bloomIntensity; }

	void setDefocus(float defocus) { this->defocus = defocus; }
	float getDefocus() const { return defocus; }

	void render(RenderTexture *src, RenderTexture *dst);

private:
	static Shader shader_glare_detection;
	static Shader shader_blur;
	static Shader shader_combine;
	//static Shader shader_tonemap;
	static const int N_PASSES = 6;

	void glareDetection(RenderTexture & src);
	void blur(RenderTexture * src, RenderTexture * dst, glm::vec2 direction);
	//void toneMap(RenderTexture * src, RenderTexture *dst);
	void combine(RenderTexture * src, RenderTexture * dst);


	ToneMapOperator toneMapOperator;
	float exposure, burnout;
	float bloomThreshold, bloomWidth, bloomIntensity;
	float defocus;

	RenderTexture glareRT;
	RenderTexture tmpRT[N_PASSES][2];

};

#endif
